本篇介紹 ES2018 (ES9) 提供的 RegExp 的 s (dotAll) flag。
本篇會有很多特殊字元,但 IT 鐵人這裡無法顯示這些字元,所以內文會看到大量的「???」XDD
.
在 RegExp 中的限制在 RegExp (regular expression,正規表達式,正規表示式) pattern 中,.
(點) 可用來 match 單一的任何字元,但在 ECMAScript 有兩個例外:
.
與 astral (即非 BMP) 字元不 match.
與 line terminator 字元不 match.
與非 BMP 字元不 match.
與 astral (即非 BMP) 字元不 match,像我們常見的 emoji 就是這種字元,以「 」為例:
/^.$/.test('?');
// false
但這個問題可用 u
( unicode
) flag 來解決:
/^.$/u.test('?');
// true
註:對 ECMAScript 來說,BMP 字元就是一個字元為一個 code point,而其他非 BMP 的字元就是兩個字元,因為這些字元是兩個 code point,只要該字元是幾個 code point,就是
length
幾。例如:'?'.length; // 2 '\uD83D\uDE0E' === '?'; // true
.
與 line terminator 字元不 matchline terminator 字元不與 .
match,常見的有 \n
和 \r
:
/^.$/.test('\n');
// false
/^.$/.test('\r');
// false
下面是在 spec 中對 line terminator 的定義:
U+000A
:LINE FEED (LF) ( \n
)U+000D
:CARRIAGE RETURN (CR) ( \r
)U+2028
:LINE SEPARATORU+2029
:PARAGRAPH SEPARATOR而下面在 spec 中對 white space 的定義:
U+0009
:CHARACTER TABULATIONU+000B
:LINE TABULATION ( \v
)U+000C
:FORM FEED (FF) ( \f
)U+0020
:SPACEU+00A0
:NO-BREAK SPACEU+FEFF
:ZERO WIDTH NO-BREAK SPACE但有時會根據情況,會將一些字元視為換行字元,例如:
U+000B
:LINE TABULATION ( \v
)U+000C
:FORM FEED (FF) ( \f
)U+0085
:NEXT LINE這就會讓 RegExp pattern 中的 .
發生一些問題:
.
不包含某些 newline 字元例如:常見的 \n
不能被 .
match:
/foo.bar/.test('foo\nbar');
// false
過去只能用一些特殊技巧來解決這個問題,例如:[\s\S]
或 [^]
:
/foo[^]bar/.test('foo\nbar');
// true
/foo[\s\S]bar/.test('foo\nbar');
// true
註:在 ECMAScript spec 的定義中,RegExp pattern 中的
\s
不只 match white space,也可 match line terminator。/\s/.test(' '); // true /\s/.test('\f'); // true /\s/.test('\n'); // true /\s/.test('\r'); // true